(function (w) {
	function jQuery(selector) {
		return new jQuery.fn.init(selector)
	}

	jQuery.fn = jQuery.prototype = {
		constructor: jQuery,
		init: function (selector) {
			if (jQuery.type(selector) === "String") {
				//Sizzle引擎 大量的正则表达式
				let elements = document.querySelectorAll(selector);
				for (let i = 0; i < elements.length; i++) {
					this[i] = elements[i];
				}
				this.length = elements.length;
			} else if (selector.nodeType) {
				//dom元素
				this[0] = selector;
				this.length = 1
			}
		}
	};

	jQuery.fn.init.prototype = jQuery.fn;

	jQuery.fn.extend = jQuery.extend = function () {
		let target, source = []; //接收数据对象，
		for (let i = 0; i < arguments.length; i++) {
			source.push(arguments[i])
		}
		//判断2种情况
		if (arguments.length === 1) {
			target = this;
			source.push(arguments[0]);
		} else {
			//参数个数大于1
			target = arguments[0];
			source.splice(0, 1);
		}
		Object.assign(target, ...source);
		return target;
	};

	jQuery.extend({
		each(obj, callBack) {
			if (length in obj && obj.length >= 0) {
				for (let i = 0; i < obj.length; i++) {
					callBack.call(obj[i], i, obj[i]);
				}
			} else {
				for (let j in obj) {
					callBack.call(obj[j], j, obj[j]);
				}
			}
		},
		type(data) {
			//判断数据的类型
			var types = Object.prototype.toString.call(data).slice(8, -1);
			return types;
		}
	});
	jQuery.fn.extend({
		each(callBack) {
			// this jQuery对象本身
			jQuery.each(this, callBack);
			return this
		}
	});
	//样式操作部分
	jQuery.fn.extend({
		css() {
			let arg1 = arguments[0];
			let arg2 = arguments[1];
			if (arguments.length === 1) {
				if (jQuery.type(arg1) === 'String') {
					//1.获取样式,只能获取第一个元素的样式
					let firstDom = this[0];
					let domStyleObj = window.getComputedStyle(firstDom, null);
					return domStyleObj[arg1];
				} else {
					let _that = this;
					//遍历出所有要添加的样式，调用css方法
					jQuery.each(arg1, function (key, value) {
						_that.css(key, value)
					});
					return _that;
				}
			} else {
				//设置样式
				return this.each(function () {//jquery的each 方法
					// this 表示一个dom元素
					this.style[arg1] = arg2
				})
			}
		},
		show() {
			//功能：所有的元素显示出来
			this.css("display", "block");
			return this;
		},
		hide() {
			this.css("display", "none");
			return this;
		},
		toggle() {
			//判断每一个元素，如果隐藏就显示，如果显示就隐藏
			this.each(function () {
				let $this = jQuery(this);
				$this[$this.css("display") === "none" ? "show" : "hide"]();
			})
		}
	});
	//事件部分
	const events = [];
	jQuery.fn.extend({
		on(type, callBack) {
			this.each(function (index, element) {
				element.addEventListener(type, callBack);
				events.push({ele: element, type, callBack})
			});
			return this;
		},
		//解除当前元素的所有的点击事件
		off(type) {
			this.each(function (index, element) {
				var evts = events.filter(function (evtObj) {
					var isCurrent = evtObj.ele === element && evtObj.type === type
					return isCurrent;
				});
				evts.forEach((evt) => {
					var {callBack} = evt;
					element.removeEventListener(type, callBack);
				})
			})
		}
	});
	w.jQuery = w.$ = jQuery;
})(window);